package com.woniu.util;

import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程安不安全：当代码在没有同步干预(加锁)的情况下，实际执行结果和预期结果一致，就是安全的，反之就是不安全
 * 非安全代码要求：对共享资源操作出现了非原子性操作，就是不安全代码！！！
 *              共享资源；线程共享
 *              非原子性操作：++，-- 等计算类操作
 * 怎么解决不安全代码：加锁！
 * 1.悲观锁
 *  1.1:本地锁（JDK）
 *      synchronized
 *      作用：可以使方法或者代码块变成同步的，同步代码块/或者同步代码：同一时间只能有一个线程进入
 *      lock：java锁接口，ReentrantLock（重入锁）
 *      ReentrantLock使用步骤
 *      1：创建锁对象
 *      2：加锁
 *      3：释放锁
 *
 *      lock
 *  1.2:本分布式锁
 *      要借助第三方工具（比如：redis就可以实现分布式锁）
 *
 * 2.乐观锁
 *
 */
@Component
public class Count {

    public int count = 10;

    ReentrantLock reentrantLock = new ReentrantLock();

    public void sub(){
        try {
//            reentrantLock.lock();//加锁.没有获取到锁的线程会一直等待
            boolean b = reentrantLock.tryLock(1, TimeUnit.SECONDS);//尝试获取锁，拿不到立马走
            if(b){
                if (count > 0){
                    count --;
                }
                Thread.sleep(1500);
            }else {
                //获取不到锁
                System.out.println("获取不到锁");
            }

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
            //捕捉异常
        } finally {
            //判断是否是当前线程自己的锁,是否进入，是否是自己的
            if (reentrantLock.isHeldByCurrentThread() && reentrantLock.isLocked()){
                reentrantLock.unlock();//释放锁.不释放就走不进来了
            }
        }

    }
}